#!/usr/bin/env python
# -*- coding:utf-8 -*-
import configparser
import os
import sys

import bottle
import threadpool
from beaker.middleware import SessionMiddleware
from bottle import PasteServer, request, response
# ------------------------------------------------------------------------------------
from paho.mqtt import client as mqtt_client

# ------------------------------------------------------------------------------------
# 公共组件------------------------------------------------------------------------------------
from comm import FileRoute
from comm import PrintInfoRoute
from comm import SysDictRoute
from comm.PrintInfoRoute import PrintInfoRoute as PrintAdm
from comm.SysDictRoute import SysDictRoute as SysDictAdm
from comm.beans.PrintInfoConfig import PrintInfoConfig
from conn.MailFactory import MyEmailConfig
from conn.MyRedisFactory import RedisConfig
# ------------------------------------------------------------------------------------
from excel import ExcelAdminRoute
from excel.EGC import EgcAdminRoute
from excel.EGC.EgcAdminRoute import EgcAdminRoute as EgcAdmin
from excel.EGC.EgcAdminService import EgcAdminService
from excel.EGI import EgiAdminRoute
from excel.EGI.EgiAdminRoute import EgiAdminRoute as EgiAdmin
from excel.EGI.EgiAdminService import EgiAdminService
from excel.ExcelAdminRoute import ExcelAdminRoute as ExcelAdmin
from excel.ExcelAdminService import ExcelAdminService
from excel.LFREE import LfreeAdminRoute
from excel.LFREE.LfreeAdminRoute import LfreeAdminRoute as LfreeAdmin
from excel.LFREE.LfreeAdminService import LfreeAdminService
from excel.PruTuutDb import PruTuutDb
from hcmv import FoodCatalogsRoute
from hcmv import MemberAddressRoute
# ------------------------------------------------------------------------------------
from hcmv import MemberWeightRoute
from hcmv import MemberWeightSeduRoute
from hcmv import WebProjectCampRoute
from hcmv import WebSubjectRoute
from hcmv import WeightLossPlanRoute
from hcmv.FoodCatalogsRoute import FoodCatalogsRoute as FoodcatAdm
from hcmv.FoodCatalogsService import FoodCatalogsService
from hcmv.MemberAddressRoute import MemberAddressRoute as MemaddrAdm
from hcmv.MemberAddressService import MemberAddressService
from hcmv.MemberWeightRoute import MemberWeightRoute as MemwetAdm
from hcmv.MemberWeightSeduRoute import MemberWeightSeduRoute as MemwetSeduAdm
from hcmv.MemberWeightService import MemeberWeightService
from hcmv.WebProjectCampRoute import WebProjectCampRoute as WebProCampAdm
from hcmv.WebProjectCampService import WebProjectCampService
from hcmv.WebSubjectRoute import WebSubjectRoute as MemsubAdm
from hcmv.WebSubjetService import WebSubjetService
from hcmv.WeightLossPlanRoute import WeightLossPlanRoute as HealthyCMVAdm
from hcmv.WeightLossPlanService import WeightLossPlanService
# ------------------------------------------------------------------------------------
from mail import MailLogRoute
from members import MemberPointLevelRoute
from members import MemberRewardHistoryRoute
from members import MemberRewardStrategyRoute
# ------------------------------------------------------------------------------------
from members import MemebersRoute
from members.MemberPointLevelRoute import MemberPointLevelRoute as MemberpotAdmin
from members.MemberPointLevelService import MemberPointLevelService
from members.MemberRewardHistoryRoute import MemberRewardHistoryRoute as MempointhisAdmin
from members.MemberRewardHistoryService import MemberRewardHistoryService
from members.MemberRewardStrategyRoute import MemberRewardStrategyRoute as MmemstrategyAdmin
from members.MemberRewardStrategyService import MemberRewardStrategyService
from members.MembersService import MembersService
from members.MemebersRoute import MemebersRoute as MemberAdmin
# ------------------------------------------------------------------------------------
from mqtt import MqttAdminRoute as MqttAdmin
from mqtt.MqttService import MqttService
from mqtt.MqttSubscriber import Subscriber
# ------------------------------------------------------------------------------------
from schedu import ScheduleAdminRoute as ScheduleAdmin, ScheduleRoute as Schedule
from schedu.ScheduleRoute import ScheduleRoute
from schedu.ScheduleService import ScheduleService

bottle.BaseRequest.MEMFILE_MAX = 10 * 1024 * 1024  # (or whatever you want)
root = bottle.Bottle()
__dir__ = os.path.dirname(os.path.abspath(__file__))
sys.path.append(__dir__)
sys.path.append(os.path.abspath(os.path.join(__dir__, '../..')))

f = r'setting.ini'
config_file = configparser.RawConfigParser()
config_file.read(f, encoding='UTF8')

session_opts = {
    'session.type': 'file',  # 以文件的方式保存session
    'session.cookei_expires': 6000,  # session过期时间为300秒
    'session.data_dir': '/tmp/sessions_dir',  # session保存目录
    'session.auto': True  # 自动保存session
}


@root.hook('before_request')
def validate():
    REQUEST_METHOD = request.environ.get('REQUEST_METHOD')
    HTTP_ACCESS_CONTROL_REQUEST_METHOD = request.environ.get('HTTP_ACCESS_CONTROL_REQUEST_METHOD')
    if REQUEST_METHOD == 'OPTIONS' and HTTP_ACCESS_CONTROL_REQUEST_METHOD:
        request.environ['REQUEST_METHOD'] = HTTP_ACCESS_CONTROL_REQUEST_METHOD


@root.hook('after_request')
def enable_cors():
    response.headers['Access-Control-Allow-Origin'] = '*'  # 允许所有域名的请求
    response.headers['Access-Control-Allow-Methods'] = 'GET, POST, DELETE, PUT, HEAD, OPTIONS'
    response.headers['Access-Control-Allow-Headers'] = 'origin,content-type,accept,authorization,x-requested-with'
    response.headers["Access-Control-Allow-Credentials"] = "true"
    response.headers['Access-Control-Max-Age'] = 86400
    response.status = 200


@root.route('/')
def index():
    # bottle.template(template_lookup=template_path.split(","), template_settings={'noescape': 1}, )
    return bottle.template('index.html')


def print_hi(host, port, template_path):
    # TODO 0 启动环境参数配置 ---------------------------------------------------------------------------------------------
    bottle.TEMPLATE_PATH = template_path.split(",")
    # TODO 1 工厂类参数配置 -----------------------------------------------------------------------------------------------
    print("TODO 1 工厂类参数配置 " + "-" * 88)
    # 1.1 Redis 参数设置
    # subscriber配置部分
    redis_cfg = config_file["redis"]
    rds_cfg = RedisConfig(host=redis_cfg['host'],
                          passwd=redis_cfg['password'],
                          port=redis_cfg['port'])
    rds_cfg.conn = RedisConfig.get_pool(rds_cfg)
    # 1.2 数据库配置连接
    pruTuut_conn = PruTuutDb.get_pool()
    # ------------------------------------ -----------------------------------------------------------------------------
    print("TODO 1.2 邮件模块参数配置 " + "-" * 76)
    # 1.2 邮件模块参数配置
    email_cfg = config_file["email_setting"]
    MyEmailConfig.host_server = email_cfg['host_server']
    MyEmailConfig.host_user = email_cfg['host_user']
    MyEmailConfig.passwd = email_cfg['passwd']
    MyEmailConfig.sender_mail = email_cfg['sender_mail']
    MyEmailConfig(email_cfg['host_server'], email_cfg['host_user'],
                  email_cfg['passwd'], email_cfg['sender_mail'])
    MyEmailConfig.get_pool()
    # ------------------------------------ -----------------------------------------------------------------------------
    quartz_cfg = config_file['quartzSetting']
    # TODO 2 服务层初始化，绑定路由事件 -------------------------------------------------------------------------------------
    # ------------------------------------ -----------------------------------------------------------------------------
    print("TODO 2.4 Java 定时任务路由参数设置 " + "-" * 76)
    # 2.4 Java 定时任务路由参数设置
    ScheduleService.base_link_url = quartz_cfg['remote_url']
    root.mount("/schedu/adm", ScheduleAdmin.scheduAdm)
    root.mount("/schedu", Schedule.schedu)
    ScheduleService()
    # ------------------------------------ -----------------------------------------------------------------------------
    print("TODO 2.5 公共插件 路由参数设置 " + "-" * 76)
    # 2.5 公共插件 路由参数设置
    root.mount("/mails", MailLogRoute.mails)
    root.mount("/file", FileRoute.file)
    mqtt_broker_cfg = config_file["mqtt_broker"]
    # 云标签打印机配置：
    yun_printer = config_file["yun_printer"]
    URL = yun_printer['URL']
    USER = yun_printer['USER']
    UKEY = yun_printer['UKEY']
    SN = yun_printer['SN']
    cfg = PrintInfoConfig(url=URL, user=USER, ukey=UKEY, sn=SN)
    root.mount("/print", PrintInfoRoute.printAdm)
    PrintAdm(cfg)
    # 2.6 系统内字典数据
    root.mount("/dict", SysDictRoute.SysDictAdm)
    SysDictAdm(pruTuut_conn)
    # ------------------------------------ -----------------------------------------------------------------------------
    print("TODO 2.7 MQTT路由参数设置 " + "-" * 76)
    # 2.7 MQTT路由参数设置
    # subscriber配置部分
    subscriber_cfg = config_file["subscriber"]
    # mqtt broker配置部分
    mqtt_broker_cfg = config_file["mqtt_broker"]
    sub = Subscriber(cfg=mqtt_client, subscriber=subscriber_cfg, mqtt_broker=mqtt_broker_cfg, is_run=True)
    root.mount("/mqtt", MqttAdmin.mqttAdm)
    MqttService()
    # ------------------------------------ -----------------------------------------------------------------------------
    print("TODO 2.7 会员管理参数设置 " + "-" * 76)
    root.mount("/mem", MemebersRoute.memberAdm)
    membersService = MembersService(pruTuut_conn)
    MemberAdmin(membersService)
    # 会员积分等级
    root.mount("/mempotlel", MemberPointLevelRoute.memberpotAdm)
    mempot_impl = MemberPointLevelService(pruTuut_conn)
    MemberpotAdmin(mempot_impl)
    # 会员积分历史记录
    root.mount("/mempothis", MemberRewardHistoryRoute.mempointhisAdm)
    mempothis_impl = MemberRewardHistoryService(pruTuut_conn)
    MempointhisAdmin(mempothis_impl)
    root.mount("/memstra", MemberRewardStrategyRoute.memstrategyAdm)
    strategyService_impl = MemberRewardStrategyService(pruTuut_conn)
    MmemstrategyAdmin(strategyService_impl)
    print("TODO 2.8 Excel2Web参数设置 " + "-" * 76)
    # 2.8 Excel2Web路由参数设置
    root.mount("/exc", ExcelAdminRoute.excelAdm)
    exe_impl = ExcelAdminService(pruTuut_conn)
    ExcelAdmin(exe_impl)
    root.mount("/lFree", LfreeAdminRoute.lFreeAdm)
    LfreeService = LfreeAdminService(pruTuut_conn)
    LfreeAdmin(LfreeService)
    root.mount("/egi", EgiAdminRoute.EgiAdm)
    EgiService = EgiAdminService(pruTuut_conn)
    EgiAdmin(EgiService)
    root.mount("/egc", EgcAdminRoute.EgcAdm)
    EgcService = EgcAdminService(pruTuut_conn)
    EgcAdmin(EgcService)
    print("TODO 2.9 健康饮食搭配参数设置 " + "-" * 76)
    # 2.9 HCMY Web 站点路由参数设置
    # 减肥计划配置
    weightLossPlanService = WeightLossPlanService(pruTuut_conn)
    # 会员健康食材计算
    memberWeightService = MemeberWeightService(pruTuut_conn)
    memberAddressService = MemberAddressService(pruTuut_conn)
    # 健康食材配置
    foodCatalogsService = FoodCatalogsService(pruTuut_conn)
    # 网站留言信息
    webSubjetService = WebSubjetService(pruTuut_conn)
    # 网站项目活动信息
    webProjectCampService = WebProjectCampService(pruTuut_conn)
    # 会员健康食材计算
    root.mount("/hcmw", MemberWeightRoute.MemwetAdm)
    root.mount("/hcmsed", MemberWeightSeduRoute.MemwetSeduAdm)
    root.mount("/hcma", MemberAddressRoute.MemaddrAdm)
    MemwetAdm(memberWeightService=memberWeightService, rds_cfg=rds_cfg)
    MemaddrAdm(memberAddressService=memberAddressService)
    MemwetSeduAdm(pru_tuut_db_conn=pruTuut_conn, mailConfig=MyEmailConfig, rds_cfg=rds_cfg,
                  memeberWeightService=memberWeightService, weightLossPlanService=weightLossPlanService)
    # 减肥计划配置
    root.mount("/hcmv", WeightLossPlanRoute.HealthyCMVAdm)
    HealthyCMVAdm(pru_tuut_db_conn=pruTuut_conn, weightLossPlanService=weightLossPlanService, rds_cfg=rds_cfg)
    # 健康食材配置
    root.mount("/hcmfc", FoodCatalogsRoute.FoodcatAdm)
    FoodcatAdm(pru_tuut_db_conn=pruTuut_conn, foodCatalogsService=foodCatalogsService)
    # 网站留言信息
    root.mount("/hcmsu", WebSubjectRoute.MemsubAdm)
    MemsubAdm(webSubjetService=webSubjetService)
    # 网站项目活动信息
    root.mount("/hcmpro", WebProjectCampRoute.WebProCampAdm)
    WebProCampAdm(webProjectCampService, memeberWeightService=memberWeightService, membersService=membersService)
    # TODO 3 启动带有session中间件的web服务 --------------------------------------------------------------------------------
    print("TODO 3 启动带有session中间件的web服务 " + "-" * 72)
    # TODO 4 启动定时任务 ------------------------------------------------------------------------------------------------
    print("TODO 4 启动定时任务 " + "-" * 90)
    # 2023-05-29 关闭自启动定时任务，改用java的quartz调用python API 接口
    ScheduleRoute.base_link_url = quartz_cfg['remote_url']
    # 4.1 启动任务队列 ------------------------------------------------------------------------------------------------
    _thread = threadpool.ThreadPool(5)
    # TODO MAIN 主线程服务启动    -----------------------------------------------------------------------------------------
    print("TODO MAIN 主线程服务启动 " + "-" * 85)
    session_app = SessionMiddleware(root, session_opts)
    bottle.run(app=session_app, server=PasteServer, host=host, port=port, debug=True)


if __name__ == '__main__':
    try:
        port = config_file['system']['port']
        host = config_file['system']['host']
        print("启动服务 %s " % (host + ":" + port))
        template_path = config_file['system']['template_path']
        print("加载服务文件HTMl路径 %s " % template_path)
        print_hi(host, port, template_path)
    except Exception as e:
        print(e)
